﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using Hi_Baidu.Cache.CacheObject;
using Hi_Baidu.Entry.CollectionObject;
using Hi_Baidu.Entry;
using Hi_Baidu.Packet.InPacket;
using Hi_Baidu.Timer;
using Hi_Baidu.Cache;

namespace Hi_Baidu.ProcessModel
{
    /// <summary>
    ///      提供了对于好友树的相关操作
    /// </summary>
    class FriendTreeViewModel : Model
    {
        private static int ADD_ITEM_COUNT = 0;
        private delegate void UPDATE_ITEM(byte[] username, TreeViewItem item, byte[] NewValue);
        /// <summary>
        ///      修改分组时的临时保存
        /// </summary>
        private static TreeViewItem ORG_MODIFY_TREEVIEWITEM;

        /// <summary>
        ///      通过好友向该好友所属分组累加上线用户数量
        /// </summary>
        /// <param name="friend">好友对象</param>
        public static void AddOnlineCountForItem(Friend friend)
        {
            AddOnlineCountForItem(friend.VisualTreeItem);
        }

        /// <summary>
        ///      通过指定分组，累加上线用户数量
        /// </summary>
        /// <param name="treeviewItem">分组</param>
        public static void AddOnlineCountForItem(TreeViewItem treeviewItem)
        {
            ((TextBlock)((Grid)treeviewItem.Header).Children[3]).Text =
                                        (int.Parse(((TextBlock)((Grid)treeviewItem.Header).Children[3]).Text)
                                            + 1).ToString();
        }

        /// <summary>
        ///      通过好友向该好友所属分组累加总共用户数量
        /// </summary>
        /// <param name="friend">好友对象</param>
        public static void AddTotalCountForItem(Friend friend)
        {
            AddTotalCountForItem(friend.VisualTreeItem);
        }

        /// <summary>
        ///      通过指定分组，累加总共用户数量
        /// </summary>
        /// <param name="treeviewItem">分组</param>
        public static void AddTotalCountForItem(TreeViewItem treeviewItem)
        {
            ((TextBlock)((Grid)treeviewItem.Header).Children[5]).Text =
                                        (int.Parse(((TextBlock)((Grid)treeviewItem.Header).Children[5]).Text)
                                            + 1).ToString();
        }

        /// <summary>
        ///     通过好友对象，减少当前在线人数
        /// </summary>
        /// <param name="friend">好友对象</param>
        public static void ReduceOnlineCountForItem(Friend friend)
        {
            //如果当前好友在线，则对应分组上线人数 - 1
            if(friend.OnlineState)
            {
                int OnlineCount = int.Parse(((TextBlock)((Grid)friend.VisualTreeItem.Header).Children[3]).Text);
                ((TextBlock)((Grid)friend.VisualTreeItem.Header).Children[3]).Text =
                                       (--OnlineCount).ToString();
            }
        }

        /// <summary>
        ///     从指定分组树节点中减少当前分组树节点的总人数
        /// </summary>
        /// <param name="treeViewItem">分组树节点</param>
        public static void ReduceTotalCountForItem(TreeViewItem treeViewItem)
        {
            ((TextBlock)((Grid)treeViewItem.Header).Children[5]).Text =
                                       (int.Parse(((TextBlock)((Grid)treeViewItem.Header).Children[5]).Text)
                                           - 1).ToString();
        }

        /// <summary>
        ///      将指定分组样式变成重命名样式结构
        /// </summary>
        /// <param name="treeviewitem"></param>
        public static void RenameItem(TreeViewItem treeviewitem)
        {
            ORG_MODIFY_TREEVIEWITEM = treeviewitem;
            Grid grid = treeviewitem.Header as Grid;
            if (grid.Children[0] is TextBox)
            {
                TextBox txt_ModifyItem = grid.Children[0] as TextBox;
                txt_ModifyItem.Text = (grid.Children[1] as TextBlock).Text;
                //显示编辑框
                txt_ModifyItem.Visibility = Visibility.Visible;
                //隐藏其他元素
                for (int i = 1; i < grid.Children.Count; i++)
                {
                    grid.Children[i].Visibility = Visibility.Collapsed;
                }
                txt_ModifyItem.KeyDown += new System.Windows.Input.KeyEventHandler(txt_ModifyItem_KeyDown);
            }
        }

        static void txt_ModifyItem_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            int Result = 0;
            Grid grid = (ORG_MODIFY_TREEVIEWITEM.Header as Grid);
            if (int.TryParse((ORG_MODIFY_TREEVIEWITEM.Tag as Item).Key,out Result))
            {
                INNER_UPDATE_ITEM_NAME(sender, e, grid);
            }
            else
            {
                INNER_ADD_ITEM_NAME(sender, e, grid);
            }
        }

        /// <summary>
        ///     内部方法 - 添加用户分组
        /// </summary>
        private static void INNER_ADD_ITEM_NAME(object sender, System.Windows.Input.KeyEventArgs e, Grid grid)
        {
            //确定添加
            if (e.Key == Key.Return)
            {
                //得到新分组名称
                String NewItemName = (sender as TextBox).Text;
                //初始化分组缓存
                ItemControlCache itemControlCache = new ItemControlCache(ItemControlCache.ItemCacheType.ADD_NEW_ITEM,
                                                                         (ORG_MODIFY_TREEVIEWITEM.Tag as Item).Key,
                                                                         NewItemName, DateTime.MaxValue);
                //打入缓存
                if(DeclareCacheManager.itemControlCacheManager.AddItemCache(itemControlCache))
                {
                    //发送新建分组请求包
                    UpdateProcessModel.AddItem(Globle.user.DIC_USERINFO["USERNAME"],
                                                          Encoding.Default.GetBytes(NewItemName), Encoding.Default.GetBytes((ORG_MODIFY_TREEVIEWITEM.Tag as Item).Key));
                    //创建超时器
                    AddItemTimeOutEvent addItemTimeOutEvent =
                        new AddItemTimeOutEvent(Globle.user.DIC_USERINFO["USERNAME"], Encoding.Default.GetBytes(NewItemName),
                                                Encoding.Default.GetBytes((ORG_MODIFY_TREEVIEWITEM.Tag as Item).Key), (ORG_MODIFY_TREEVIEWITEM.Tag as Item).Key, 2000, 3);
                    //打入超时器
                    Globle.timeoutTimerManager.InstallTimer(addItemTimeOutEvent);
                    //还原该分组原来的默认样式
                    grid.Children[0].Visibility = Visibility.Collapsed;
                    for (int i = 1; i < grid.Children.Count; i++)
                    {
                        grid.Children[i].Visibility = Visibility.Visible;
                    }
                }
                else
                {
                    throw new Exception("添加新分组，打入缓存集合失败");
                }
            }
        }

        /// <summary>
        ///     内部方法 - 更新用户分组名称
        /// </summary>
        private static void INNER_UPDATE_ITEM_NAME(object sender, System.Windows.Input.KeyEventArgs e, Grid grid)
        {
            //确定修改
            if (e.Key == Key.Return)
            {
                String NewItemName = "";
                if ((NewItemName = (sender as TextBox).Text) != (grid.Children[1] as TextBlock).Text)
                {
                    //获得新的分组名 --> 为该分组创建分组缓存器
                    ItemControlCache itemControlCache = new ItemControlCache(
                        ItemControlCache.ItemCacheType.UPDATE_ITEM, (ORG_MODIFY_TREEVIEWITEM.Tag as Item).Key,
                        NewItemName, DateTime.MaxValue);
                    //如果打入缓存失败
                    if (!DeclareCacheManager.itemControlCacheManager.AddItemCache(itemControlCache))
                    {
                        throw new Exception("打入分组缓存失败...!");
                    }
                    byte[] NV = Encoding.Default.GetBytes(NewItemName);
                    //发送缓存更改请求
                    System.Windows.Application.Current.Dispatcher.Invoke(
                                                                                                            DispatcherPriority.Background,
                                                                                                            new UPDATE_ITEM
                                                                                                            (
                                                                                                                UpdateProcessModel.UpdateItem),
                                                                                                                Globle.user.DIC_USERINFO["USERNAME"],
                                                                                                                new object[] { ORG_MODIFY_TREEVIEWITEM, NV }
                                                                                                             );

                    //创建更新分组超时器
                    UpdateItemTimeOutEvent updateItemTimeOutEvent =
                        new UpdateItemTimeOutEvent(Globle.user.DIC_USERINFO["USERNAME"],
                                                   ORG_MODIFY_TREEVIEWITEM,
                                                   Encoding.Default.GetBytes(NewItemName), "UpdateItem" + (ORG_MODIFY_TREEVIEWITEM.Tag as Item).Key,
                                                   2000, 3);
                    //打入超时器
                    Globle.timeoutTimerManager.InstallTimer(updateItemTimeOutEvent);
                    //还原该分组原来的默认样式
                    grid.Children[0].Visibility = Visibility.Collapsed;
                    for (int i = 1; i < grid.Children.Count; i++)
                    {
                        grid.Children[i].Visibility = Visibility.Visible;
                    }
                }
            }
        }

        /// <summary>
        ///     设置指定分组名称为新的名称
        /// </summary>
        /// <param name="inpackage">更新分组请求回馈包</param>
        public static void SetItemName(UpdateItemReplyPacket inpackage)
        {
            //找到对用的分组树节点
            var treeViewItem = from TreeViewItem treeviewitem in Globle.win_Main.TV_FriendList.Items
                               where (treeviewitem.Tag as Item).Key == inpackage.GetItemId()
                               select treeviewitem;
            foreach (TreeViewItem item in treeViewItem)
            {
                if (DeclareCacheManager.itemControlCacheManager.Equals(inpackage.GetItemId()))
                {
                    //赋值新分组名称
                    ((item.Header as Grid).Children[1] as TextBlock).Text =
                        (DeclareCacheManager.itemControlCacheManager.GetMemberByKey(inpackage.GetItemId()) as ItemControlCache).Value;
                     //从分组集合中更新
                    Item Newitem = Globle.itemCollection.GetMemberByKey(inpackage.GetItemId()) as Item;
                    if (Newitem != null)
                    {
                        Newitem.UpdateName((DeclareCacheManager.itemControlCacheManager.GetMemberByKey(inpackage.GetItemId()) as ItemControlCache).Value);
                    }
                    //移除该分组缓存
                    DeclareCacheManager.itemControlCacheManager.RemoveItemCache(inpackage.GetItemId());
                    break;
                }
            }
        }

        /// <summary>
        ///     添加新分组到好友树
        /// </summary>
        public static void AddItem()
        {
            Item item = new Item("新分组" + ADD_ITEM_COUNT, "新分组" + ADD_ITEM_COUNT);
            RenameItem(MainBoardViewModel.AddItem(item));
            ADD_ITEM_COUNT++;
        }

        /// <summary>
        ///     将具有指定KEY的树节点分组从好友树中移除
        /// </summary>
        /// <param name="ItemKey">分组KEY</param>
        public static void ReturnItem(String ItemKey)
        {
            foreach (TreeViewItem treeViewItem in Globle.win_Main.TV_FriendList.Items)
            {
                if ((treeViewItem.Tag as Item).Key == ItemKey)
                {
                    Globle.win_Main.TV_FriendList.Items.Remove(treeViewItem);
                    break;
                }
            }
        }

        /// <summary>
        ///     创建分组成功后, 将新创建的分组名称改写
        /// </summary>
        public static void SetAddItem(AddItemReplyPacket inpackage)
        {
            ItemControlCache itemControlCache =
                DeclareCacheManager.itemControlCacheManager.GetMemberByKey(inpackage.GetItemKey()) as ItemControlCache;
            if (itemControlCache != null)
            {
                //找到好友树中对应的分组
                var treeViewItem = from TreeViewItem treeviewitem in Globle.win_Main.TV_FriendList.Items
                                   where (treeviewitem.Tag as Item).Key == inpackage.GetItemKey()
                                   select treeviewitem;
                foreach (TreeViewItem item in treeViewItem)
                {
                    //重新赋值该分组名称
                    ((item.Header as Grid).Children[1] as TextBlock).Text = itemControlCache.Value;
                    //重新赋值该分组KEY
                    (item.Tag as Item).Key = inpackage.GetItemId();
                    //新建分组对象到分组集合
                    Item Newitem = new Item(inpackage.GetItemId(), itemControlCache.Value);
                    Globle.itemCollection.Add(Newitem);
                    //移除缓存
                    DeclareCacheManager.itemControlCacheManager.RemoveItemCache(itemControlCache);
                    break;
                }
            }
        }

        /// <summary>
        ///     删除选定的分组
        /// </summary>
        public static void DeleteItem()
        {
            TreeViewItem SelectedItem = Globle.win_Main.TV_FriendList.SelectedItem as TreeViewItem;
            //确认当前选中的树节点是分组而且不为空
            if (SelectedItem != null && (SelectedItem.Tag is Item))
            {
                //初始化分组缓存
                ItemControlCache itemControlCache = new ItemControlCache(ItemControlCache.ItemCacheType.DELETE_ITEM,
                                                                         "DeleteItem" + (SelectedItem.Tag as Item).Key,
                                                                         (SelectedItem.Tag as Item).Name, DateTime.MaxValue);
                //将分组缓存打入缓存集合
                if (DeclareCacheManager.itemControlCacheManager.AddItemCache(itemControlCache))
                {
                    //向服务器发送删除分组请求包
                    UpdateProcessModel.DeleteItem(Globle.user.DIC_USERINFO["USERNAME"], BitConverter.GetBytes(int.Parse((SelectedItem.Tag as Item).Key)));
                    //初始化删除分组超时器
                    DeleteItemTimeOutEvent deleteItemTimeOutEvent =
                        new DeleteItemTimeOutEvent(Globle.user.DIC_USERINFO["USERNAME"],
                                                   BitConverter.GetBytes(int.Parse((SelectedItem.Tag as Item).Key)),
                                                   "DeleteItem" + (SelectedItem.Tag as Item).Key, 2000, 3);
                    //打入超时器集合
                    Globle.timeoutTimerManager.Add(deleteItemTimeOutEvent);
                }
                else
                {
                    throw new Exception("添加删除分组缓存失败!");
                }
            }
        }

        /// <summary>
        ///     从好友树中移除已经删除的用户分组
        /// </summary>
        /// <param name="inpackage"></param>
        public static void SetDeleteItem(DeleteItemReplyPacket inpackage)
        {
            //从好友树中找到对应分组 --> 删除
            var treeViewItem = from TreeViewItem treeviewitem in Globle.win_Main.TV_FriendList.Items
                               where (treeviewitem.Tag as Item).Key == inpackage.GetItemId()
                               select treeviewitem;
            foreach (TreeViewItem item in treeViewItem)
            {
                //移除该分组
                Globle.win_Main.TV_FriendList.Items.Remove(item);
                break;
            }

            //从分组集合中删除
            Globle.itemCollection.Remove(inpackage.GetItemId());
        }
    }
}
